;; midi-client.scm - (c) rohan drape, 2002-2005

;; Interface to the midi.osc server.

;; The data type to store state information about a midi client.

(define-structure midi-client (osc-transport))

(define (midi-client-address m)
  (osc-transport-address (midi-client-osc-transport m)))

(define (midi-client-host-address m)
  (network-address-host-address (midi-client-address m)))

(define (midi-client-host-name m)
  (network-address-host-name (midi-client-address m)))

(define (midi-client-port-number m)
  (network-address-port-number (midi-client-address m)))

;; Make a connection to a midi.osc server.  Dispatch all incoming midi
;; messages to the RSC 'midi-receiver' system.  The default values for
;; `host-name' and `port-number' are those of midi.osc on the local
;; host.

(defineK (midi-connect (host-name "127.0.0.1") 
		       (port-number 57150))
  (let ((u (make-osc-transport (resolve-network-address host-name 
							port-number))))
    (osc-receiver-register 
     "/midi" 
     (lambda (packet) 
       (midi-receiver-dispatch (u8vector->list (third packet)))))
    (osc-send u '("/receive" #xFFF))
    (make-midi-client u)))

;; Send the midi message described by `status-byte' and any number of
;; `data-bytes' to `midi-port'.

(define (midi-send midi-client midi-port status-byte . data-bytes)
  (osc-send 
   (midi-client-osc-transport midi-client)
   (list "/midi" 
	 midi-port
	 (list->u8vector (cons status-byte data-bytes)))))

;; Disconnect from the midi.osc server.

(define (midi-disconnect midi-client)
  (let ((u (midi-client-osc-transport midi-client)))
    (osc-send u '("/receive" -1))
    (osc-transport-stop u)))

;; Procedure to start an instance of the midi.osc server.

(defineK (midi-start-server (server "midi.osc") (port 57150))
  (system (format "~a -p ~a &" server port)))
